<template><div><h2 id="缓存系统" tabindex="-1"><a class="header-anchor" href="#缓存系统"><span>缓存系统</span></a></h2>
<ul>
<li><a href="#introduction">简介</a></li>
<li><a href="#configuration">配置</a>
<ul>
<li><a href="#driver-prerequisites">驱动的前提条件</a></li>
</ul>
</li>
<li><a href="#cache-usage">缓存使用</a>
<ul>
<li><a href="#obtaining-a-cache-instance">获取缓存实例</a></li>
<li><a href="#retrieving-items-from-the-cache">从缓存获取数据</a></li>
<li><a href="#storing-items-in-the-cache">向缓存存储数据</a></li>
<li><a href="#removing-items-from-the-cache">从缓存删除数据</a></li>
<li><a href="#the-cache-helper">Cache 辅助函数</a></li>
</ul>
</li>
<li><a href="#cache-tags">缓存标记</a>
<ul>
<li><a href="#storing-tagged-cache-items">存储被标记的缓存数据</a></li>
<li><a href="#accessing-tagged-cache-items">访问被标记的缓存数据</a></li>
<li><a href="#removing-tagged-cache-items">删除被标记的缓存数据</a></li>
<li><a href="#pruning-stale-cache-tags">清理过期的缓存标记</a></li>
</ul>
</li>
<li><a href="#atomic-locks">原子锁</a>
<ul>
<li><a href="#lock-driver-prerequisites">驱动的前提条件</a></li>
<li><a href="#managing-locks">管理锁</a></li>
<li><a href="#managing-locks-across-processes">跨进程管理锁</a></li>
</ul>
</li>
<li><a href="#adding-custom-cache-drivers">添加自定义缓存驱动</a>
<ul>
<li><a href="#writing-the-driver">编写驱动</a></li>
<li><a href="#registering-the-driver">注册驱动</a></li>
</ul>
</li>
<li><a href="#events">事件</a></li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>在某些应用中，一些查询数据或处理任务的操作会在某段时间里短时间内大量进行，或是一个操作花费好几秒钟。当出现这种情况时，通常会将检索到的数据缓存起来，从而为后面请求同一数据的请求迅速返回结果。这些缓存数据通常会储存在极快的存储系统中，例如 <a href="https://memcached.org/" target="_blank" rel="noopener noreferrer">Memcached</a> 和 <a href="https://redis.io/" target="_blank" rel="noopener noreferrer">Redis</a>。</p>
<p>Laravel 为各种缓存后端提供了富有表现力且统一的 API，以便你利用它们极快的查询数据来加快你的应用。</p>
<h2 id="配置" tabindex="-1"><a class="header-anchor" href="#配置"><span>配置</span></a></h2>
<p>缓存配置文件位于 <code v-pre>config/cache.php</code>。在这个文件中，你可以指定应用默认使用哪个缓存驱动。Laravel 支持的缓存后端包括 <a href="https://memcached.org/" target="_blank" rel="noopener noreferrer">Memcached</a>、<a href="https://redis.io/" target="_blank" rel="noopener noreferrer">Redis</a>、<a href="https://aws.amazon.com/dynamodb" target="_blank" rel="noopener noreferrer">DynamoDB</a>，以及现成的关系型数据库。此外，还支持基于文件的缓存驱动，以及方便自动化测试的缓存驱动 <code v-pre>array</code> 和 <code v-pre>null</code> 。</p>
<p>缓存配置文件还包含文件中记录的各种其他选项，因此请务必阅读这些选项。 默认情况下，Laravel 配置为使用 <code v-pre>file</code> 缓存驱动，它将序列化的缓存对象存储在服务器的文件系统中。 对于较大的应用程序，建议你使用更强大的驱动，例如 Memcached 或 Redis。 你甚至可以为同一个驱动配置多个缓存配置。</p>
<h3 id="驱动先决条件" tabindex="-1"><a class="header-anchor" href="#驱动先决条件"><span>驱动先决条件</span></a></h3>
<h4 id="database" tabindex="-1"><a class="header-anchor" href="#database"><span>Database</span></a></h4>
<p>使用 <code v-pre>database</code> 缓存驱动时，你需要设置一个表来包含缓存项。你将在下表中找到 <code v-pre>Schema</code> 声明的示例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Schema</span><span class="token operator">::</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'cache'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Blueprint</span> <span class="token variable">$table</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$table</span><span class="token operator">-></span><span class="token keyword type-declaration">string</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">unique</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token variable">$table</span><span class="token operator">-></span><span class="token function">text</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'value'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token variable">$table</span><span class="token operator">-></span><span class="token function">integer</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'expiration'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
你还可以使用 <code v-pre>php artisan cache:table</code> Artisan 命令生成具有适当模式的迁移。</p>
</blockquote>
<h4 id="memcached" tabindex="-1"><a class="header-anchor" href="#memcached"><span>Memcached</span></a></h4>
<p>使用 Memcached 驱动程序需要安装 <a href="https://pecl.php.net/package/memcached" target="_blank" rel="noopener noreferrer">Memcached PECL 包</a>。你可以在 <code v-pre>config/cache.php</code> 配置文件中列出所有的 Memcached 服务器。该文件已经包含一个 <code v-pre>memcached.servers</code> 来帮助你入门：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'memcached'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'servers'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'host'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'MEMCACHED_HOST'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'127.0.0.1'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'port'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'MEMCACHED_PORT'</span><span class="token punctuation">,</span> <span class="token number">11211</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'weight'</span> <span class="token operator">=></span> <span class="token number">100</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果需要，你可以将 <code v-pre>host</code> 选项设置为 UNIX socket 的路径。 如果这样做， <code v-pre>port</code> 选项应设置为 <code v-pre>0</code>：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'memcached'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'host'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'/var/run/memcached/memcached.sock'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'port'</span> <span class="token operator">=></span> <span class="token number">0</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'weight'</span> <span class="token operator">=></span> <span class="token number">100</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="redis" tabindex="-1"><a class="header-anchor" href="#redis"><span>Redis</span></a></h4>
<p>在将 Redis 缓存与 Laravel 一起使用之前，您需要通过 PECL 安装 PhpRedis PHP 扩展或通过 Composer 安装 <code v-pre>predis/predis</code> 包（~1.0）。<a href="https://learnku.com/docs/laravel/10.x/sail" target="_blank" rel="noopener noreferrer">Laravel Sail</a> 已经包含了这个扩展。另外，Laravel 官方部署平台如 <a href="https://forge.laravel.com/" target="_blank" rel="noopener noreferrer">Laravel Forge</a> 和 <a href="https://vapor.laravel.com/" target="_blank" rel="noopener noreferrer">Laravel Vapor</a> 也默认安装了 PhpRedis 扩展。</p>
<p>有关配置 Redis 的更多信息，请参阅其 <a href="https://learnku.com/docs/laravel/10.x/redis#configuration" target="_blank" rel="noopener noreferrer">Laravel documentation page</a>.</p>
<h4 id="dynamodb" tabindex="-1"><a class="header-anchor" href="#dynamodb"><span>DynamoDB</span></a></h4>
<p>在使用 <a href="https://aws.amazon.com/dynamodb" target="_blank" rel="noopener noreferrer">DynamoDB</a> 缓存驱动程序之前，您必须创建一个 DynamoDB 表来存储所有缓存的数据。通常，此表应命名为<code v-pre>cache</code>。但是，您应该根据应用程序的缓存配置文件中的 <code v-pre>stores.dynamodb.table</code> 配置值来命名表。</p>
<p>该表还应该有一个字符串分区键，其名称对应于应用程序的缓存配置文件中的 <code v-pre>stores.dynamodb.attributes.key</code> 配置项的值。 默认情况下，分区键应命名为 <code v-pre>key</code>。</p>
<h2 id="缓存用法" tabindex="-1"><a class="header-anchor" href="#缓存用法"><span>缓存用法</span></a></h2>
<h3 id="获取缓存实例" tabindex="-1"><a class="header-anchor" href="#获取缓存实例"><span>获取缓存实例</span></a></h3>
<p>要获取缓存存储实例，您可以使用 <code v-pre>Cache</code> 门面类，我们将在本文档中使用它。<code v-pre>Cache</code> 门面类提供了对 Laravel 缓存底层实现的方便、简单的访问：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Cache</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 显示应用程序所有用户的列表。</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">index</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">array</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$value</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token comment">// ...</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="访问多个缓存存储" tabindex="-1"><a class="header-anchor" href="#访问多个缓存存储"><span>访问多个缓存存储</span></a></h4>
<p>使用 <code v-pre>Cache</code> 门面类, 您可以通过 <code v-pre>store</code> 方法访问各种缓存存储。传递给 <code v-pre>store</code> 方法的键应该对应于 <code v-pre>cache</code> 配置文件中的 <code v-pre>stores</code> 配置数组中列出的存储之一：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$value</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">store</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'file'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'foo'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">store</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'redis'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'bar'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'baz'</span><span class="token punctuation">,</span> <span class="token number">600</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10 分钟</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="从缓存中检索项目" tabindex="-1"><a class="header-anchor" href="#从缓存中检索项目"><span>从缓存中检索项目</span></a></h3>
<p><code v-pre>Cache</code> 门面的 <code v-pre>get</code> 方法用于从缓存中检索项目。如果缓存中不存在该项目，则将返回 <code v-pre>null</code>。如果您愿意，您可以将第二个参数传递给 <code v-pre>get</code> 方法，指定您希望在项目不存在时返回的默认值：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$value</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$value</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'default'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>您甚至可以将闭包作为默认值传递。如果指定的项在缓存中不存在，则返回闭包的结果。传递闭包允许您推迟从数据库或其他外部服务中检索默认值：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$value</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token comment">/* ... */</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="检查项目是否存在" tabindex="-1"><a class="header-anchor" href="#检查项目是否存在"><span>检查项目是否存在</span></a></h4>
<p><code v-pre>has</code> 方法可用于确定缓存中是否存在项目。如果项目存在但其值为 <code v-pre>null</code>，此方法也将返回 <code v-pre>false</code>：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">has</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// ...</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="递增-递减值" tabindex="-1"><a class="header-anchor" href="#递增-递减值"><span>递增 / 递减值</span></a></h4>
<p><code v-pre>increment</code> 和 <code v-pre>decrement</code> 方法可用于调整缓存中整数项的值。这两种方法都接受一个可选的第二个参数，指示增加或减少项目值的数量：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">increment</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">increment</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token variable">$amount</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">decrement</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">decrement</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token variable">$amount</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="检索和存储" tabindex="-1"><a class="header-anchor" href="#检索和存储"><span>检索和存储</span></a></h4>
<p>有时你可能希望从缓存中检索一个项目，但如果请求的项目不存在，则存储一个默认值。 例如， 你可能希望从缓存中检索所有用户，如果用户不存在，则从数据库中检索并将它们添加到缓存中。 你可以使用 <code v-pre>Cache::remember</code> 方法执行此操作：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$value</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">remember</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">,</span> <span class="token variable">$seconds</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果该项不存在于缓存中，将执行传递给 <code v-pre>remember</code> 方法的闭包，并将其结果放入缓存中。</p>
<p>你可以使用 <code v-pre>rememberForever</code> 方法从缓存中检索一个项目，如果它不存在则永久存储它：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$value</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">rememberForever</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="检索和删除" tabindex="-1"><a class="header-anchor" href="#检索和删除"><span>检索和删除</span></a></h4>
<p>如果你需要从缓存中检索一项后并删除该项，你可以使用 <code v-pre>pull</code> 方法。 与 <code v-pre>get</code> 方法一样，如果该项不存在于缓存中，将返回 <code v-pre>null</code>：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$value</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">pull</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="在缓存中存储项目" tabindex="-1"><a class="header-anchor" href="#在缓存中存储项目"><span>在缓存中存储项目</span></a></h3>
<p>你可以使用 <code v-pre>Cache</code> Facade上的 <code v-pre>put</code> 方法将项目存储在缓存中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">,</span> <span class="token variable">$seconds</span> <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>如果存储时间没有传递给 <code v-pre>put</code> 方法，则该项目将无限期存储：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>除了将秒数作为整数传递之外，你还可以传递一个代表缓存项所需过期时间的 <code v-pre>DateTime</code> 实例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">,</span> <span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">addMinutes</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="如果不存在则存储" tabindex="-1"><a class="header-anchor" href="#如果不存在则存储"><span>如果不存在则存储</span></a></h4>
<p><code v-pre>add</code> 方法只会将缓存存储中不存在的项目添加到缓存中。如果项目实际添加到缓存中，该方法将返回 <code v-pre>true</code>。 否则，该方法将返回 <code v-pre>false</code>。 <code v-pre>add</code> 方法是一个原子操作：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">,</span> <span class="token variable">$seconds</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="永久存储" tabindex="-1"><a class="header-anchor" href="#永久存储"><span>永久存储</span></a></h4>
<p><code v-pre>forever</code> 方法可用于将项目永久存储在缓存中。由于这些项目不会过期，因此必须使用 <code v-pre>forget</code> 方法手动将它们从缓存中删除：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">forever</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
如果您使用的是 Memcached 驱动程序，则当缓存达到其大小限制时，可能会删除「永久」存储的项目。</p>
</blockquote>
<h3 id="从缓存中删除项目" tabindex="-1"><a class="header-anchor" href="#从缓存中删除项目"><span>从缓存中删除项目</span></a></h3>
<p>您可以使用 <code v-pre>forget</code> 方法从缓存中删除项目：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">forget</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>您还可以通过提供零或负数的过期秒数来删除项目：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>您可以使用 <code v-pre>flush</code> 方法清除整个缓存：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">flush</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
刷新缓存不会考虑您配置的缓存「缓存」，并且会从缓存中删除所有条目。在清除由其他应用程序共享的缓存时，请考虑到这一点。</p>
</blockquote>
<h3 id="缓存助手函数" tabindex="-1"><a class="header-anchor" href="#缓存助手函数"><span>缓存助手函数</span></a></h3>
<p>除了使用 <code v-pre>Cache</code> 门面之外，您还可以使用全局 <code v-pre>cache</code> 函数通过缓存检索和存储数据。当使用单个字符串参数调用 <code v-pre>cache</code> 函数时，它将返回给定键的值：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$value</span> <span class="token operator">=</span> <span class="token function">cache</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>如果您向函数提供键 / 值对数组和过期时间，它将在指定的持续时间内将值存储在缓存中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token function">cache</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'key'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token variable">$seconds</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token function">cache</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'key'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'value'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">addMinutes</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当不带任何参数调用 cache 函数时，它会返回 Illuminate\Contracts\Cache\Factory 实现的实例，允许您调用其他缓存方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token function">cache</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">remember</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">,</span> <span class="token variable">$seconds</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p><strong>技巧</strong><br>
在测试对全局 <code v-pre>cache</code> 函数的调用时，您可以使用 <code v-pre>Cache::shouldReceive</code> 方法，就像 <a href="https://learnku.com/docs/laravel/10.x/mocking#mocking-facades" target="_blank" rel="noopener noreferrer">testing the facade</a>.</p>
</blockquote>
<h2 id="缓存标签" tabindex="-1"><a class="header-anchor" href="#缓存标签"><span>缓存标签</span></a></h2>
<blockquote>
<p><strong>注意</strong><br>
使用 <code v-pre>file</code>, <code v-pre>dynamodb</code> 或 <code v-pre>database</code> 存驱动程序时不支持缓存标记。 此外，当使用带有「永久」存储的缓存的多个标签时，使用诸如「memcached」之类的驱动程序会获得最佳性能，它会自动清除陈旧的记录。</p>
</blockquote>
<h3 id="存储缓存标签" tabindex="-1"><a class="header-anchor" href="#存储缓存标签"><span>存储缓存标签</span></a></h3>
<p>缓存标签允许您在缓存中标记相关项目，然后刷新所有已分配给定标签的缓存值。您可以通过传入标记名称的有序数组来访问标记缓存。例如，让我们访问一个标记的缓存并将一个值<code v-pre>put</code>缓存中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">tags</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'people'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'artists'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'John'</span><span class="token punctuation">,</span> <span class="token variable">$john</span><span class="token punctuation">,</span> <span class="token variable">$seconds</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">tags</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'people'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'authors'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Anne'</span><span class="token punctuation">,</span> <span class="token variable">$anne</span><span class="token punctuation">,</span> <span class="token variable">$seconds</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="访问缓存标签" tabindex="-1"><a class="header-anchor" href="#访问缓存标签"><span>访问缓存标签</span></a></h3>
<p>要检索标记的缓存项，请将相同的有序标签列表传递给 tags 方法，然后使用您要检索的键调用 <code v-pre>get</code> 方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$john</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">tags</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'people'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'artists'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'John'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$anne</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">tags</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'people'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'authors'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Anne'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="删除被标记的缓存数据" tabindex="-1"><a class="header-anchor" href="#删除被标记的缓存数据"><span>删除被标记的缓存数据</span></a></h3>
<p>你可以刷新所有分配了标签或标签列表的项目。 例如，此语句将删除所有标记有 <code v-pre>people</code>, <code v-pre>authors</code>或两者的缓存。因此，<code v-pre>Anne</code> 和 <code v-pre>John</code> 都将从缓存中删除：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">tags</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'people'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'authors'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">flush</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>相反，此语句将仅删除带有 <code v-pre>authors</code> 标记的缓存，因此将删除 <code v-pre>Anne</code>，但不会删除 <code v-pre>John</code>：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">tags</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'authors'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">flush</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="清理过期的缓存标记" tabindex="-1"><a class="header-anchor" href="#清理过期的缓存标记"><span>清理过期的缓存标记</span></a></h3>
<blockquote>
<p><strong>注意</strong><br>
仅在使用 Redis 作为应用程序的缓存驱动程序时，才需要清理过期的缓存标记。</p>
</blockquote>
<p>为了在使用 Redis 缓存驱动程序时正确清理过期的缓存标记，Laravel 的 Artisan 命令 <code v-pre>cache:prune-stale-tags</code> 应该被添加到 <a href="https://learnku.com/docs/laravel/10.x/scheduling" target="_blank" rel="noopener noreferrer">任务调度</a> 中，在应用程序的 <code v-pre>App\Console\Kernel</code> 类里：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$schedule</span><span class="token operator">-></span><span class="token function">command</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'cache:prune-stale-tags'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">hourly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="原子锁" tabindex="-1"><a class="header-anchor" href="#原子锁"><span>原子锁</span></a></h2>
<blockquote>
<p><strong>注意</strong><br>
要使用此功能，您的应用程序必须使用<code v-pre>memcached</code>、<code v-pre>redis</code>、<code v-pre>dynamodb</code>、<code v-pre>database</code>、<code v-pre>file</code>或<code v-pre>array</code>缓存驱动程序作为应用程序的默认缓存驱动程序。<br>
此外，所有服务器都必须与同一中央缓存服务器通信。</p>
</blockquote>
<h3 id="驱动程序先决条件" tabindex="-1"><a class="header-anchor" href="#驱动程序先决条件"><span>驱动程序先决条件</span></a></h3>
<h4 id="数据库" tabindex="-1"><a class="header-anchor" href="#数据库"><span>数据库</span></a></h4>
<p>使用“数据库”缓存驱动程序时，您需要设置一个表来包含应用程序的缓存锁。您将在下表中找到一个示例 <code v-pre>Schema</code> 声明：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Schema</span><span class="token operator">::</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'cache_locks'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Blueprint</span> <span class="token variable">$table</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$table</span><span class="token operator">-></span><span class="token keyword type-declaration">string</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">primary</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token variable">$table</span><span class="token operator">-></span><span class="token keyword type-declaration">string</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'owner'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token variable">$table</span><span class="token operator">-></span><span class="token function">integer</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'expiration'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="管理锁" tabindex="-1"><a class="header-anchor" href="#管理锁"><span>管理锁</span></a></h3>
<p>原子锁允许操作分布式锁而不用担心竞争条件。例如，<a href="https://forge.laravel.com/" target="_blank" rel="noopener noreferrer">Laravel Forge</a> 使用原子锁来确保服务器上一次只执行一个远程任务。您可以使用 <code v-pre>Cache::lock</code> 方法创建和管理锁：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Cache</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$lock</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'foo'</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$lock</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 锁定 10 秒…</span></span>
<span class="line"></span>
<span class="line">    <span class="token variable">$lock</span><span class="token operator">-></span><span class="token function">release</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code v-pre>get</code> 方法也接受一个闭包。闭包执行后，Laravel 会自动释放锁：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'foo'</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 锁定 10 秒并自动释放...</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果在您请求时锁不可用，您可以指示 Laravel 等待指定的秒数。如果在指定的时间限制内无法获取锁，则会抛出 Illuminate\Contracts\Cache\LockTimeoutException：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Cache<span class="token punctuation">\</span>LockTimeoutException</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$lock</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'foo'</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">try</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$lock</span><span class="token operator">-></span><span class="token function">block</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token comment">// 等待最多 5 秒后获得的锁...</span></span>
<span class="line"><span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">LockTimeoutException</span> <span class="token variable">$e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 无法获取锁…</span></span>
<span class="line"><span class="token punctuation">}</span> <span class="token keyword">finally</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$lock</span><span class="token operator">?-></span><span class="token function">release</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>上面的例子可以通过将闭包传递给 <code v-pre>block</code> 方法来简化。当一个闭包被传递给这个方法时，Laravel 将尝试在指定的秒数内获取锁，并在闭包执行后自动释放锁：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'foo'</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">block</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 等待最多 5 秒后获得的锁...</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="跨进程管理锁" tabindex="-1"><a class="header-anchor" href="#跨进程管理锁"><span>跨进程管理锁</span></a></h3>
<p>有时，您可能希望在一个进程中获取锁并在另一个进程中释放它。例如，您可能在 Web 请求期间获取锁，并希望在由该请求触发的排队作业结束时释放锁。在这种情况下，您应该将锁的作用域<code v-pre>owner token</code>传递给排队的作业，以便作业可以使用给定的令牌重新实例化锁。</p>
<p>在下面的示例中，如果成功获取锁，我们将调度一个排队的作业。 此外，我们将通过锁的<code v-pre>owner</code>方法将锁的所有者令牌传递给排队的作业：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$podcast</span> <span class="token operator">=</span> <span class="token class-name static-context">Podcast</span><span class="token operator">::</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$lock</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'processing'</span><span class="token punctuation">,</span> <span class="token number">120</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$lock</span><span class="token operator">-></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">ProcessPodcast</span><span class="token operator">::</span><span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token variable">$podcast</span><span class="token punctuation">,</span> <span class="token variable">$lock</span><span class="token operator">-></span><span class="token function">owner</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在我们应用程序的<code v-pre>ProcessPodcast</code>作业中，我们可以使用所有者令牌恢复和释放锁：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">restoreLock</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'processing'</span><span class="token punctuation">,</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">owner</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">release</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>如果你想释放一个锁而不考虑它的当前所有者，你可以使用<code v-pre>forceRelease</code>方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'processing'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">forceRelease</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="添加自定义缓存驱动" tabindex="-1"><a class="header-anchor" href="#添加自定义缓存驱动"><span>添加自定义缓存驱动</span></a></h2>
<h3 id="编写驱动" tabindex="-1"><a class="header-anchor" href="#编写驱动"><span>编写驱动</span></a></h3>
<p>要创建我们的自定义缓存驱动程序，我们首先需要实现<code v-pre>Illuminate\Contracts\Cache\Store</code> <a href="https://learnku.com/docs/laravel/10.x/contracts" target="_blank" rel="noopener noreferrer">contract</a>。 因此，MongoDB 缓存实现可能如下所示：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Extensions</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Cache<span class="token punctuation">\</span>Store</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">MongoStore</span> <span class="token keyword">implements</span> <span class="token class-name">Store</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">get</span><span class="token punctuation">(</span><span class="token variable">$key</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">many</span><span class="token punctuation">(</span><span class="token keyword type-hint">array</span> <span class="token variable">$keys</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">put</span><span class="token punctuation">(</span><span class="token variable">$key</span><span class="token punctuation">,</span> <span class="token variable">$value</span><span class="token punctuation">,</span> <span class="token variable">$seconds</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">putMany</span><span class="token punctuation">(</span><span class="token keyword type-hint">array</span> <span class="token variable">$values</span><span class="token punctuation">,</span> <span class="token variable">$seconds</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">increment</span><span class="token punctuation">(</span><span class="token variable">$key</span><span class="token punctuation">,</span> <span class="token variable">$value</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">decrement</span><span class="token punctuation">(</span><span class="token variable">$key</span><span class="token punctuation">,</span> <span class="token variable">$value</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">forever</span><span class="token punctuation">(</span><span class="token variable">$key</span><span class="token punctuation">,</span> <span class="token variable">$value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">forget</span><span class="token punctuation">(</span><span class="token variable">$key</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">flush</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">getPrefix</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>我们只需要使用 MongoDB 连接来实现这些方法中的每一个。有关如何实现这些方法的示例，请查看 <a href="https://github.com/laravel/framework" target="_blank" rel="noopener noreferrer">Laravel 框架源代码</a>中的<code v-pre>Illuminate\Cache\MemcachedStore</code>。 一旦我们的实现完成，我们可以通过调用<code v-pre>Cache</code> 门面的<code v-pre>extend</code>方法来完成我们的自定义驱动程序注册：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">extend</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'mongo'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Application</span> <span class="token variable">$app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">repository</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">MongoStore</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p><strong>技巧</strong><br>
如果你想知道将自定义缓存驱动程序代码放在哪里，可以在你的<code v-pre>app</code>目录中创建一个<code v-pre>Extensions</code>命名空间。 但是请记住，Laravel 没有严格的应用程序结构，你可以根据自己的喜好自由组织应用程序。</p>
</blockquote>
<h3 id="注册驱动" tabindex="-1"><a class="header-anchor" href="#注册驱动"><span>注册驱动</span></a></h3>
<p>要向 Laravel 注册自定义缓存驱动程序，我们将使用<code v-pre>Cache</code>门面的<code v-pre>extend</code>方法。 由于其他服务提供者可能会尝试在他们的<code v-pre>boot</code>方法中读取缓存值，我们将在<code v-pre>booting</code>回调中注册我们的自定义驱动程序。 通过使用<code v-pre>booting</code>回调，我们可以确保在应用程序的服务提供者调用<code v-pre>boot</code>方法之前但在所有服务提供者调用<code v-pre>register</code>方法之后注册自定义驱动程序。 我们将在应用程序的<code v-pre>App\Providers\AppServiceProvider</code>类的<code v-pre>register</code>方法中注册我们的<code v-pre>booting</code>回调：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Providers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Extensions<span class="token punctuation">\</span>MongoStore</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Application</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Cache</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>ServiceProvider</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">CacheServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 注册任何应用程序服务。</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">register</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token property">app</span><span class="token operator">-></span><span class="token function">booting</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">             <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">extend</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'mongo'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Application</span> <span class="token variable">$app</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">                 <span class="token keyword">return</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">repository</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">MongoStore</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">             <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">         <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 引导任何应用程序服务。</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">// ...</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>传递给<code v-pre>extend</code>方法的第一个参数是驱动程序的名称。这将对应于<code v-pre>config/cache.php</code>配置文件中的 <code v-pre>driver</code>选项。 第二个参数是一个闭包，它应该返回一个<code v-pre>Illuminate\Cache\Repository</code>实例。闭包将传递一个<code v-pre>$app</code>实例，它是<a href="https://learnku.com/docs/laravel/10.x/container" target="_blank" rel="noopener noreferrer">服务容器</a>的一个实例。</p>
<p>注册扩展程序后，将<code v-pre>config/cache.php</code>配置文件的<code v-pre>driver</code>选项更新为扩展程序的名称。</p>
<h2 id="事件" tabindex="-1"><a class="header-anchor" href="#事件"><span>事件</span></a></h2>
<p>要在每个缓存操作上执行代码，你可以侦听缓存触发的 <a href="https://learnku.com/docs/laravel/10.x/events" target="_blank" rel="noopener noreferrer">events</a> 。 通常，你应该将这些事件侦听器放在应用程序的<code v-pre>App\Providers\EventServiceProvider</code>类中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Listeners<span class="token punctuation">\</span>LogCacheHit</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Listeners<span class="token punctuation">\</span>LogCacheMissed</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Listeners<span class="token punctuation">\</span>LogKeyForgotten</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Listeners<span class="token punctuation">\</span>LogKeyWritten</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Cache<span class="token punctuation">\</span>Events<span class="token punctuation">\</span>CacheHit</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Cache<span class="token punctuation">\</span>Events<span class="token punctuation">\</span>CacheMissed</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Cache<span class="token punctuation">\</span>Events<span class="token punctuation">\</span>KeyForgotten</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Cache<span class="token punctuation">\</span>Events<span class="token punctuation">\</span>KeyWritten</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 应用程序的事件侦听器映射。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@var</span> <span class="token class-name"><span class="token keyword">array</span></span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">protected</span> <span class="token variable">$listen</span> <span class="token operator">=</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token class-name static-context">CacheHit</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name static-context">LogCacheHit</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">CacheMissed</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name static-context">LogCacheMissed</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">KeyForgotten</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name static-context">LogKeyForgotten</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">KeyWritten</span><span class="token operator">::</span><span class="token keyword">class</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name static-context">LogKeyWritten</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/10.x/cache/14861" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/10.x/ca...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/10.x/cache/14861" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/10.x/ca...</a></p>
</blockquote>
</div></template>


